/**!
 * FileName: common.js
 * Copyright (c) 2011-2012 sotee, http://www.sotee.com
 */
/***
 * -CLASS-
 * @name Sotee
 * @description 本类主要负责为sotee.com站的页面提供公共方法(静态对象)。
 * @syntax 静态类，使用 [ Sotee.方法名 ] 直接调用
 * @author benben
 * @version 2011-07-19
 * @since 1.0
 */
var Sotee = {
	/**
	 * -METHOD-
	 * @description 返回指定字符串的单节长度。
	 * @method Sotee.abslen
	 * @param arg String 
	 *				被操作的目标字符串。
	 * @return Number
	 * @since 1.0
	 */
	abslen: function(arg) {
		return (arg || "").replace(/[^\x00-\xff]/g, "##").length;
	},
	/**
	 * -METHOD-
	 * @description 返回指定字符串集合中最大的字符串长度(单字节)。
	 * @method Sotee.maxlen
	 * @param list Array 
	 *				被操作的目标字符串集合。
	 * @param list:item String
	 * 				字符串成员
	 * @return Number
	 * @since 1.0
	 */
	maxlen: function(list) {
		var len = 0, tmp;
		list.constructor == Array
			&& $(list).each(function(a, b) {
				(tmp = Sotee.abslen(b)) > len && (len = tmp);
			});
		return len;
	},
	//用于把字符进行Html转义操作的一个对象
	div: $("<div/>"),
	/**
	 * -METHOD-
	 * @description 返回指定字符串的HTML形式。
	 * @method Sotee.toHtml
	 * @param arg String 
	 *				被操作的目标字符串。
	 * @return String
	 * @since 1.0
	 */
	toHtml: function(arg) {
		return this.div.text(arg).html();
	},
	/**
	 * -METHOD-
	 * @description 初始化画面中的搜索栏。
	 * 				此方法必须在页面加载完成后才可以调用！
	 * @method Sotee.initSearchBar
	 * @param list Array 
	 *				分类选择面板的所有成员。
	 * @param list:item String
	 * 				下拉面板分类名称项
	 * @since 1.0
	 */
	initSearchBar: function(list) {
		var searchBar = $("#searchBar"), seaPanel = $(".seaClassPanel"),
			seaText = $(".seaText"), keyWord,
			itemCode = [], defaultText = "请输入搜索关键字";
		//构建分类面板
		seaPanel.length && seaPanel.remove();
		$(list).each(function(idx, item){
			itemCode.push("<li idx=", idx, " >", item, "</li>");
		});
		(seaPanel = $("<ul/>")).addClass("seaClassPanel")
			.html(itemCode.join('')).appendTo($("body")).hide().children()
			.hover(function(){
				$(this).addClass("seaSeleItem");
			}, function(){
				$(this).removeClass("seaSeleItem");
			}).mousedown(function() {
				seaText.text(this.innerHTML).attr("idx", this.getAttribute("idx"));
				seaPanel.hide();
			});
		//分类选择按钮
		$(".searchClassBtn")
			.click(function(event) {
				event.stopPropagation();
				seaPanel.css("top", searchBar.offset().top + 29)
					.css("left", searchBar.offset().left + 4).show();
				document.body.onmousedown = function() {
					seaPanel.hide();
					document.body.onmousedown = null;
				};
			});
		keyWord = $(".keyField");
		//搜索按钮的事件回调
		$(".searchBtn").click(function(tmp) {
			(tmp = keyWord.val()) == defaultText && (tmp = "");
			Sotee.seaBtnAction
				&& Sotee.seaBtnAction(seaText.attr("idx"), seaText.text(), tmp);
		});
	},
	/**
	 * -METHOD-
	 * @description 初始化外链配置画面中的链接搜索栏。
	 * 				此方法必须在页面加载完成后才可以调用！
	 * @method Sotee.initClassSearchBar
	 * @param list Array 
	 *				分类选择面板的所有成员。
	 * @param list:item String
	 * 				下拉面板分类名称项
	 * @param barId String 
	 *				搜索栏的Id，默认值：.cellBorder。
	 * @param classBtnId String 
	 *				分类下拉框按钮的Id，默认值：.seleClassBtn。
	 * @param clsTxtId String 
	 *				分类文本框的Id，默认值：#classTxt。
	 * @param keywordId String 
	 *				关键字文本框的Id，默认值：.seleKeyword。
	 * @param callBack Function 
	 *				搜索按钮的单击事件回调函数，默认值：Sotee.seaLnkBtnAction。
	 * @since 1.0
	 */
	initClassSearchBar: function(list, barId, classBtnId, clsTxtId, keywordId, seaBtn, callBack) {
		var searchBar = $(barId || ".cellBorder"), seaText = $(clsTxtId || "#classTxt"),
			itemCode = [], defaultText = "请输入链接过虑关键字...", keyWord, seaPanel;
		$(list).each(function(idx, item){
			itemCode.push("<li idx=", idx, " >", item, "</li>");
		});
		(seaPanel = $("<ul/>")).addClass("seaLnkClassPanel").width(134)
			.html(itemCode.join('')).appendTo($("body")).hide().children()
			.hover(function(){
				$(this).addClass("seaSeleItem");
			}, function(){
				$(this).removeClass("seaSeleItem");
			}).mousedown(function() {
				seaText = $(clsTxtId || "#classTxt").last();
				seaText.text(this.innerHTML).attr("idx", this.getAttribute("idx"));
				seaPanel.hide();
			});
		//分类选择按钮
		$(classBtnId || ".seleClassBtn")
			.click(function(event) {
				event.stopPropagation();
				searchBar = $(barId || ".cellBorder").last();
				seaPanel.css("top", searchBar.offset().top + 26)
					.css("left", searchBar.offset().left + 1).show();
				document.body.onmousedown = function() {
					seaPanel.hide();
					document.body.onmousedown = null;
				};
			});
		//搜索按钮的事件回调
		$(seaBtn || ".searchLnkBtn").click(function(tmp) {
			keyWord = $(keywordId || ".seleKeyword").last();
			(tmp = keyWord.val()) == defaultText && (tmp = "");
			(callBack || Sotee.seaLnkBtnAction)
				(seaText.attr("idx"), seaText.text(), tmp);
		});
	},
	/**
	 * -METHOD-
	 * @description 搜索按钮的单击事件回调函数，可以通过重写本方法来处理搜索功能。
	 * @method Sotee.seaBtnAction
	 * @param tIdx String
	 *				搜索分类的选择项索引。
	 * @param type String 
	 *				搜索分类的选择项文本。
	 * @param keyword String 
	 *				被搜索关键字。
	 * @since 1.0
	 */
	seaBtnAction: function(tIdx, type, keyword) {
		alert("typeIdx:" + tIdx + "---type:"+type + "----keyword:" + keyword);
	},
	/**
	 * -METHOD-
	 * @description 外链搜索按钮的单击事件回调函数，可以通过重写本方法来处理外链搜索功能。
	 * @method Sotee.seaLnkBtnAction
	 * @param tIdx String
	 *				搜索分类的选择项索引。
	 * @param type String 
	 *				搜索分类的选择项文本。
	 * @param keyword String 
	 *				被搜索关键字。
	 * @since 1.0
	 */
	seaLnkBtnAction: function(tIdx, type, keyword) {
		alert("typeIdx:" + tIdx + "---type:"+type + "----keyword:" + keyword);
	},
	/**
	 * -METHOD-
	 * @description 初始化页面悬停提示组件。
	 * 				将页面中带有tip属性的HTML标签自动添加悬停提示功能，悬停提示的=>
	 * 				内容就是tip属性的值。
	 * @method Sotee.initHelpTipBox
	 * @since 1.0
	 */
	initHelpTipBox: function() {
		var tipBox = $("<div/>"), text, pos;
		//构建悬停提示面板
		tipBox.addClass("tipBoxWrap").html([
			"<div class=tip-lt><div class=tip-rt><div class=tip-t></div></div></div>",
			"<div class='tip-body font'></div>", "<div class=tip-lb><div class=tip-rb>",
			"<div class=tip-b align=left><div class=tip-arrow></div></div></div></div>"
		].join('')).appendTo($("body")).hide();
		text = $(".tip-body");
		//悬停提示的事件触发
		$("[tip]").hover(function() {
			var tip = this.getAttribute("tip"), len;
			if(tip) {
				len = Sotee.maxlen(tip.split("\\n")) + 1;
				text.html(Sotee.toHtml(tip).replace(/\\n/g, "<br/>"));
				pos = $(this).offset();
				tipBox.width(len * 6 + 4)
					.css("top", pos.top -tipBox.height() - 4)
					.css("left", pos.left - 22)
					.stop().hide().css("opacity", "0.85").fadeIn();
			}//Endif
		}, function() {
			tipBox.fadeOut();
		});
	},
	/**
	 * -METHOD-
	 * @description 初始化画面中的组面板控件。
	 * 				此方法必须在页面加载完成后才可以调用！
	 * @method Sotee.initGroupPanel
	 * @param id String
	 * 				组面板标签父节点的节点ID。
	 * @since 1.0
	 */
	initGroupPanel: function(id) {
		var gp = $(id), pnList = gp.children().filter("div");
		//重构组面板结构
		$("b", gp).each(function(idx, item) {
			this.isExpand = this.getAttribute("isExpand") == "true";
			!$(this).attr("noCount")
				&& (this.innerHTML += "(" + $("label", pnList[idx]).length + ")");
			$("<div/>").addClass(this.isExpand ? "gp-expand" : "")
				.html('<div class=gp-caption-wrap><div class=gp-caption></div></div>')
				.append($(pnList[idx]).addClass("gp-panel"))
				.appendTo(gp).find(".gp-caption").append(this);
		});
		//添加事件控制
		$("b", gp).addClass("gp-text").click(function() {
			$(this.parentNode.parentNode.parentNode)[
				(this.isExpand = !this.isExpand) ? "addClass" : "removeClass"
			]("gp-expand");
		});
	},
	/**
	 * -METHOD-
	 * @description 初始化画面中的信息提示框。
	 * 				调用该方法以后，可以通过 {@link # Sotee.showMsgBox} 方法显示提示信息！
	 * @method Sotee.initMsgBox
	 * @since 1.0
	 */
	initMsgBox: function() {
		$([
			"<div align=right class=msgBoxTop><a href='javascript:void(0);' class=msgBoxClsBtn>X",
			"</a><div class=msgBoxBtm><div align=left class=msgBoxBody></div></div></div>"
		].join('')).appendTo("body").hide().find(".msgBoxClsBtn").click(function() {
			Sotee.hideMsgBox();
		});
	},
	/**
	 * -METHOD-
	 * @description 显示信息提示框。
	 * @method Sotee.showMsgBox
	 * @param id String
	 * 				信息提示框面板的标签ID。
	 * @since 1.0
	 */
	showMsgBox: function(id) {
		var panel = $(".msgBoxBody");
		if(!panel.length) return;
		panel.children().hide().appendTo("body");
		panel.append($(id)).children().first().show();
		var w = $(window), d = document,
			dd = d.documentElement, msg = $(".msgBoxTop");
		msg.css("left", (w.width() - msg.width()) / 2)
			.css("top", (w.height() - msg.height()) / 2
				+ (dd.scrollTop || d.body.scrollTop)).show();
	},
	/**
	 * -METHOD-
	 * @description 隐藏信息提示框。
	 * @method Sotee.hideMsgBox
	 * @since 1.0
	 */
	hideMsgBox: function() {
		$(".msgBoxTop").hide();
	},
	/**
	 * -METHOD-
	 * @description 初始化页面中的选项卡控件。
	 * @method Sotee.initTabBar
	 * @param id String
	 * 				选项卡在页面中的标签ID。
	 * @param option JSON
	 * @param option:type Number
	 * 				选项卡的类型，不同类型的样式不同，取值：[0, 1, 2]。
	 * @param option:panels String
	 * 				选项卡面板的页面标签ID。
	 * @param option:callback Function
	 * 				选项卡的onChange事件的回调函数，调用该函数时会把当前的Tab对象做=>
	 * 				为参数传入。
	 * @param option:tabs Array
	 * 				选项卡的参数集合。
	 * @param option:tabs:item JSON
	 * 				单个选项卡的参数。
	 * @param option:tabs:item:text String
	 * 				子选项卡的标题。
	 * @param option:tabs:item:blank Number
	 * 				子选项卡标题两端的空白宽度，默认值：24。
	 * @param option:tabs:item:panel String
	 * 				子选项卡面板在页面中的标签ID。
	 * @since 1.0
	 */
	initTabBar: function(id, option) {
		$(id).tabbar(option);
	},
	/**
	 * -METHOD-
	 * @description 将页面中的指定DIV渲染成好友列表控件。
	 * @method Sotee.initFriendList
	 * @param id String
	 * 				好友列表在页面中的标签ID。
	 * @param option JSON
	 * @param option:width Number
	 * 				好友列表控件的宽度。
	 * @param option:height Number
	 * 				好友列表控件的高度。
	 * @param option:groups Array
	 * 				好友列表的分组数据。
	 * @param option:groups:item JSON
	 * 				groups成员的语法。
	 * @param option:groups:item:caption String
	 * 				好友分组的组标题名称。
	 * @param option:tabs:item:isExpand boolean
	 * 				好友分组初始化时是否为展开状态。
	 * @param option:tabs:item:list Array
	 * 				好友分组成员项的参数集合。
	 * 				成员语法：{ text: String|好友的名称, icon: String|好友的头像的URL }
	 * @since 1.0
	 */
	initFriendList: function(id, option) {
		$(id).friendList(option);
	},
	/**
	 * -METHOD-
	 * @description 初始化页面的表单验证控件。
	 * 				使用本方法需要预先加载表单验证插件：jq.validform.js / validform.css
	 * @method Sotee.initValidform
	 * @param selecter String
	 * 				需要添加验证功能的表单的选择符。
	 * @param option JSON 初始化控件的配置参数
	 * @param option:btnSubmit String
	 * 				(可选) 表单提交按钮的ID，如果表单内含有submit按钮的话，该参数可省略。
	 * @param option:tipType Number
	 * 				(可选) 验证信息的提示类型，1：弹出式，2：边框式，默认值：1。
	 * @param option:postonce boolean
	 * 				(可选) 是否开启网速慢时的二次提交防御，默认不开启，默认值：false。
	 * @param option:ajaxPost boolean
	 * 				(可选) 是否使用ajax方式提交表单数据，默认不开启，默认值：false；
	 * 				提交地址就是form的action所指向的地址。
	 * @param option:callback Function
	 * 				(可选) Ajax验证后的回调函数。
	 * 				该函数有一个JSON类型的参数，参数格式：{ info: String, status: String }；
	 * 				参数 -> info：要输出的提示信息；
	 * 				参数 -> status：返回提交数据后的校验状态，该参数可以在后台自行约定；
	 * @since 1.0
	 */
	initValidform: function(id, option) {
		$(id).validform(option);
	},
	/**
	 * -METHOD-
	 * @description 初始化页面的下拉列表树控件。
	 * 				本方法需要在页面加载完成后才可调用，调用完本方法后才可以进行控制渲染。
	 * @method Sotee.initComboBoxTree
	 * @param option JSON
	 * 				初始化控件的配置参数
	 * @param option:id String
	 * 				下拉列表树控件的页面标签ID。
	 * @param option:treecontrol String
	 * 				下拉列表树控件的功能按键容器的页面标签ID。
	 * @param option:width Number
	 * 				下拉列表树控件的宽度，默认值：200px。
	 * @param option:height Number
	 * 				下拉列表树控件的高度，默认值：26px。
	 * @param option:panelWidth Number
	 * 				下拉列表树控件的下拉面板宽度，默认值：控件的宽度。
	 * @param option:panelHeight Number
	 * 				下拉列表树控件的下拉面板高度，默认值：200px。
	 * @param option:expandDeep Number
	 * 				初始化时，树节点的默认展开级别。
	 * @param option:action Function
	 * 				控件的onChange事件。
	 * @param option:data JSON
	 * 				下拉列表树的节点数据
	 * @param option:data:id String
	 * 				下拉列表树节点的ID。
	 * @param option:data:text String
	 * 				下拉列表树节点的文本名称。
	 * @param option:data:nodeList Array
	 * 				下拉列表树节点的子节点。
	 * @param option:data:nodeList:item JSON
	 * 				nodeList成员的语法结构与option.data相同
	 * @since 1.0
	 */
	initComboBoxTree: function(option) {
		var nt = [
			'<ul>', '<li', ' class="closed"', '><span class="folder"><tt value="',
			'"><nobr>', '</nobr></tt></span>', '</li>', '</ul>'
		], field = $(option.id)
			.html('<a href="javascript:void(0)" tabIndex="0"></a><div>我的所有文件</div>'),
		panel = $('<div class="jq-comboTree-panelWrap"/>'),
		focusEl = field.find("a"), text, html = [], isShow, isOver, pos,
		over = function() { isOver = true; },
		out = function() { isOver = false; },
		//隐藏下拉面板
		hidePanel = function() {
			panel.hide();
			isShow = false;
		};
		option.width = option.width || 200;
		option.height = option.height || 26;
		option.treecontrol = option.treecontrol || "treecontrol";
		//下拉面板
		panel.html([
			'<div align="right" id="', option.treecontrol,'">', '<a href="javascript:void(0)">',
			'<img src="/soteeTemplate/image/file/minus.gif" border="0"/> [ 收起全部 ]</a>',
			'<a href="javascript:void(0)">',
			'<img src="/soteeTemplate/image/file/plus.gif" border="0"/> [ 展开全部 ]</a>',
			'</div>'].join(''))
				.width(option.panelWidth || option.width)
				.appendTo("body").hover(over, out).mousedown(function() {
					setTimeout(function(){focusEl.focus()}, 0);
				});
		//构建Dom树
		~function(nd, lv) {
			html.push(nt[1], lv < option.expandDeep ? "" :
				nt[2], nt[3], nd.id, nt[4], nd.text, nt[5]);
			if(nd.nodeList && nd.nodeList.length) {
				html.push(nt[0]);
				for (var i = -1; ++i < nd.nodeList.length;) {
					arguments.callee(nd.nodeList[i], lv + 1);
				}//Endfor
				html.push(nt[7]);
			}//Endif
			html.push(nt[6]);
		}(option.data, 0);
		var a = $('<ul class="filetree"/>').addClass("jq-comboTree-panel")
			.height(option.panelHeight || 200)
			.html(html.join('')).appendTo(panel).treeview({
				control: "#" + option.treecontrol, overClass: "focusItem",
				//树节点的单击事件回调
				action: function() {
					hidePanel();
					text.text($(this).text()).attr("value", $(this).attr("value"));
					option.action && option.action(this);
				}
			})[0].onmousewheel = function(event) {
				var evt = event || window.event;
				return this.scrollTop
			};
		//ComboField
		field.width(option.width)
			.addClass("jq-comboTreeField").mousedown(function() {
				!isShow && setTimeout(function(){focusEl.focus()}, 0);
			});
		//控件的焦点对象
		focusEl.blur(function() {
			!isOver && hidePanel();
		}).focus(function() {
			pos = field.offset();
			panel.css("top", pos.top + option.height + 3).css("left", pos.left).show();
			isShow = true;
		});
		text = field.find("div").width(option.width - 28)
			.height(option.height).css("line-height", option.height + "px");
	}
};
///EndClass-Sotee

/**!
 * -CLASS-
 * @name TabBar
 * @description 本类主要负责将页面中的指定DIV渲染成选项卡控件，=>
 * 				参数说明请参见{@link # tabbar}方法中的说明
 * @syntax JQ插件，使用 [ $("DIV的").tabbar(初始化参数); ] 直接调用
 * @author benben
 * @version 2011-07-27
 * @since 1.0
 */
//选项卡模板
jQuery.fn.tbTemplate = [
	"<div style='width:","px;float:left' pid=", "><div class=s-tb-left>",
	"<div class=s-tb-right><div class=s-tb-body><div class=s-tb-text>",
	"</div></div></div></div></div>"
];
//样式表
jQuery.fn.tbStyle = [
	"tab-type-a", "tab-type-b", "tab-type-c"
];
//将页面中的指定DIV渲染成选项卡控件
jQuery.fn.tabbar = function(option) {
	var tpl = this.tbTemplate, html = [],
		panels = $(option.panels), tab;
	//构建Dom结构
	$(option.tabs).each(function(idx, item) {
		html.push(tpl[0], Sotee.abslen(item.text) * 7 + (item.blank || 24));
		html.push(tpl[1], item.panel)
		!idx && html.push(' class=s-tb-select');
		html.push(tpl[2], tpl[3], item.text, tpl[4]);
		$(item.panel)[idx ? "hide" : "show"]().appendTo(panels);
	});
	//设置样式及事件控制
	tab = $(this).html(html.join(''))
		//设置TabBar的样式
		.addClass(this.tbStyle[option.type])
		.children().click(function(){
			$(tab.removeClass("s-tb-select").attr("pid")).hide();
			$((tab = $(this).addClass("s-tb-select")).attr("pid")).show();
			option.callback && option.callback($(this));
		});
	option.type < 2 && tab.css("margin-right", "2px");
	//默认选择项
	tab = tab.first();
};

/**!
 * -CLASS-
 * @name Friends
 * @description 本类主要负责将页面中的指定DIV渲染成好友分组列表控件，=>
 * 				参数说明请参见{@link # friendList}方法中的说明
 * @syntax JQ插件，使用 [ $("DIV的").friendList(初始化参数); ] 直接调用
 * @author benben
 * @version 2011-07-28
 * @since 1.0
 */
//好友列表模板
jQuery.fn.flTemplate = {
	group: [
		'<div class=', '><div class=fl-groupCaption>',
		'</div><div class=fl-panel>', '</div></div>'
	],
	item: [
		'<div class=fl-item><img align=absmiddle src="', '"/>', '</div>'
	]
};
//将页面中的指定DIV渲染成好友列表控件
jQuery.fn.friendList = function(option) {
	var tpl = this.flTemplate,
		gt = tpl.group, it = tpl.item, html = [], tmp,
	//组遍历函数
	fn1 = function(idx, item) {
		tmp = item.list ? item.list.length : 0;
		html.push(gt[0]);
		item.isExpand && html.push("fl-expand");
		html.push(gt[1], item.caption, " [ ", tmp, " ]", gt[2]);
		item.list && $(item.list).each(fn2);
		html.push(gt[3]);
	},
	//项遍历函数
	fn2 = function(idx, item) {
		html.push(it[0], item.icon, it[1], item.text, it[2]);
	};
	//构建Dom结构
	$(option.groups).each(fn1);
	$(this).width(option.width).height(option.height)
		.addClass("friendsList").html(html.join(''))
		.find(".fl-groupCaption").click(function() {
			var el = this.parentNode;
			el.className = el.className ? "" : "fl-expand";
		});
	//鼠标事件
	$(".fl-item").hover(function() {
		$(this).css("background-color", "#c5e4f9");
	}, function() {
		$(this).css("background-color", "");
	}).click(function() {
		$("#iptText").val($(this).text()).css("color", "#111");
	});
}

try {
	document.execCommand("BackgroundImageCache", false, true);
}catch(e) {}

~function() {
	//页面初始化
	$(document).ready(function(){
		//textField的默认值
		$("[defaultTxt]").each(function(){
			$(this).val(this
				.dftTxt = $(this).attr("defaultTxt")).css("color", "#ccc");
		}).focus(function() {
			this.value == this.dftTxt
				&& (this.value = "", this.style.color = "#111");
		}).blur(function() {
			!this.value
				&& (this.value= this.dftTxt, this.style.color = "#ccc");
		});
		//初始化搜索栏
		Sotee.initSearchBar(["分类1","分类2","分类3","分类4","分类5"]);
		//初始Tip组件
		Sotee.initHelpTipBox();
	});
}();
